// 切换高度
export function toggleHeight(el, { speed = 0.3, timing = 'ease-out', callback }) {
	el.style.transition = `height ${speed}s ${timing}`; // 设置动画
	// 初始化高度为 0
	if (el.clientHeight === 0) {
		el.style.height = 'auto';
		const height = el.clientHeight;
		el.style.height = '0px';
		window.setTimeout(() => {
			el.style.height = `${height}px`;
			if (callback) callback(height);
		}, 0);
	} else {
		el.style.height = '0px';
		if (callback) callback(0);
	}
}

// 动画
/**
 *
 * @param {String} style 要过渡的样式属性
 * @param {Number} target 目标值
 * @param {Number} speed 动画速度(毫秒)
 * @param {String} get 取值函数，需要返回 Number 类型的数值
 * @param {String} set 赋值函数，需要返回包含单位的style样式值
 */
export function animate(el, { style, target, speed = 0.3, get = (val) => val, set = (val) => val, callback }) {
	if (!style) return;
	let timer = null;
	const steps = []; // 过渡动画的样式变化步骤
	const styleValue = el.style[style];
	steps.push(styleValue ? Number.parseFloat(get(styleValue)) : 0); // 获取元素过渡动画样式初始值
	const isPercentage = target <= 10; // 判断动画目标值是否小于10(小于10时会出现小数缺失计算精度引起计算错误)

	if (isPercentage) target *= 100; // 小于10的动画目标值按百分比计算

	timer = window.setInterval(function () {
		let curStep = steps[steps.length - 1]; // 获取最新样式动画值

		if (isPercentage) curStep *= 100; // 小于10的动画步值按百分比计算

		// 步值达到目标值时，步骤计算结束
		if (curStep === target) {
			clearInterval(timer);

			// 动画开始
			const speedTime = speed * 1000; // 动画过渡时间(毫秒)
			const delay = speedTime / steps.length; // 动画执行间隔(毫秒)
			let animateStep = 0; // 当前动画过渡步骤

			const animateTimer = window.setInterval(() => {
				// 动画步骤执行结束
				if (animateStep >= steps.length) {
					clearInterval(animateTimer);
					if (callback) callback();
					return;
				}

				el.style[style] = set(steps[animateStep]); // 样式赋值
				animateStep++;
			}, delay);
			return;
		}

		let step = (target - curStep) / 10; // 计算每一步动画过渡值(渐减)
		step = step > 0 ? Math.ceil(step) : Math.floor(step);
		step += curStep; // 样式动画过渡值
		if (isPercentage) step /= 100; // 按百分比还原样式动画步骤值
		steps.push(Number.parseFloat(step.toFixed(2))); // 保留小数点后两位
	}, 0);
}

// 是否包含指定类名
export function hasClass(el, cls) {
	if (!el || !cls) return false;
	if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
	if (el.classList) {
		return el.classList.contains(cls);
	} else {
		return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
	}
}
